-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement UnixFileMode APIs #69980
Implement UnixFileMode APIs #69980
Conversation
Note regarding the This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, to please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change. |
Tagging subscribers to this area: @dotnet/area-system-io Issue DetailsImplements #67837.
|
Currently this only has the Unix implementation, and there are no tests yet. The implementation relies on some methods that are added in #60507. I'll rebase when that PR is merged. Can you give me some pointers on what APIs I should use for this on Windows (to get/set the mode as WSL/NTFS metadata)? |
I looked into what it would mean to support this APi on Windows in the context of WSL2. Per this Linux files are stored in NTFS using a file system plugin called VolFS. WSL2 can access Windows files using a plugin called DrvFS.
To read extended attributes you can use NtQueryEaFile, but it's apparently not documented (only ZwQueryEaFile which drivers can use). I haven't found a documented Win32 that allows you to do it. @JeremyKuhne do you have insight here? Although, even if it is documented, it's not clear to me that there is much value in wiring this up for Windows, because it apparently will only enable it for files in the Windows filesystem written by WSL distros and only then that have the non-default metadata config flag enabled. So perhaps this API should just throw on Windows. BTW I found https://github.com/ladislav-zezula/FileTest a very helpful UI for experimenting with NtQueryEaFile. |
I also think the value is low. If a user would like to have the unix permissions with WSL, they can set the mount options (
Proposing something: For the APIs that create a file/directory, I think they shouldn't throw because that facilitates using them in cross-platform code. |
That seems to be what chmod will do in WSL on a Windows file if 'metadata' flag is not used. But if it is set, it would now be a misleading result, as it should be interpreting the extended attributes. |
This is akin to someone asking that files have a specific permission level set and then silently ignoring it, e.g. "create this file so that only I can read it" and then it silently enables everyone to read it. That seems like a security incident waiting to happen. |
ok, let's avoid confusion and make it throw.
The property/argument is named If we're not going to ignore it on Windows, a user will need to conditionalize for Windows to make their code work xplat. |
Presumably if they're trying to lock the file down, they'd need to do this anyway to use ACLs on Windows. |
I like it when code that works for me on Linux doesn't throw PNSE on Windows. Also, I think/hope a user setting And, not all use-cases that require unix permissions need a Windows ACL, like the tar extracting, for example. I'll implement it to throw PNSE. We can revisit it later, if we want |
I agree with failing on Windows for now -- perhaps we will learn more from WSL team, or their support will evolve, which might make it more interesting. |
src/libraries/System.Private.CoreLib/src/System/IO/FileStatus.Unix.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Windows.cs
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs
Outdated
Show resolved
Hide resolved
@danmoseley As long as the |
if (actualMode != UserReadWrite) | ||
{ | ||
throw new CryptographicException(SR.Format(SR.Cryptography_InvalidFilePermissions, stream.Name)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note: I've omitted the owner check that was in EnsureFilePermissions
since it is implicit from only the owner having permissions and us being able to open the file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, big thanks for your contribution @tmds!
src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.Unix.cs
Show resolved
Hide resolved
@@ -53,7 +54,9 @@ public abstract partial class TarEntry | |||
// If the permissions weren't set at all, don't write the file's permissions. | |||
if (permissions != 0) | |||
{ | |||
Interop.CheckIo(Interop.Sys.FChMod(handle, permissions), destinationFileName); | |||
#pragma warning disable CA1416 // Validate platform compatibility |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@buyaa-n @ViktorHofer the File.SetUnixFileMode
method is marked as [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("windows")]
and this particular C# file is compiled only for Unix:
<ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'Unix'"> | |
<Compile Include="System\Formats\Tar\TarEntry.Unix.cs" /> |
Is it expected that the compiler produces warning?
src/libraries/System.IO.FileSystem/tests/Base/BaseGetSetUnixFileMode.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem/tests/Base/BaseGetSetUnixFileMode.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem/tests/Directory/CreateDirectory_UnixFileMode.Unix.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem/tests/FileStream/ctor_options.Unix.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.IO.FileSystem/tests/FileStream/FileStreamOptions.cs
Outdated
Show resolved
Hide resolved
[UnsupportedOSPlatform("windows")] | ||
public static void SetUnixFileMode(SafeFileHandle fileHandle, UnixFileMode mode) | ||
=> SetUnixFileModeCore(fileHandle, mode); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All these methods throw PlatformNotSupportedException
on Windows, I think that it would be good to include this information in the docs.
/// <exception cref="PlatformNotSupportedException">Not supported on Windows.</exception>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it need to be added when it is marked with the UnsupportedOSPlatformAttribute
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@buyaa-n what is the guidance for such scenarios?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Idk what is the guidance for documenting, though I know that the attribute would showed up on the API doc like this:
https://docs.microsoft.com/en-us/dotnet/api/system.console.in?view=net-6.0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm only seeing 11 places that do this in the current codebase, but we throw PNSE in many, many other places. So I'm not sure this is strictly necessary.
src/libraries/System.Private.CoreLib/src/Resources/Strings.resx
Outdated
Show resolved
Hide resolved
Co-authored-by: Adam Sitnik <[email protected]>
@@ -22,7 +22,9 @@ public static partial class ZipFileExtensions | |||
// include the permissions, or was made on Windows. | |||
if (permissions != 0) | |||
{ | |||
Interop.CheckIo(Interop.Sys.FChMod(fs.SafeFileHandle, permissions), fs.Name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can the Interop file be removed from this .csproj?
@@ -59,7 +59,6 @@ | |||
<Compile Include="$(CommonPath)Interop\Unix\System.Native\Interop.FChMod.cs" Link="Common\Interop\Unix\System.Native\Interop.FChMod.cs" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great! Thank you for all the great work here, @tmds!
My latest comments can be addressed in a follow up PR if we don't want to reset CI and want to merge today in order to make the preview 6 cutoff.
@eerhardt @adamsitnik we can merge this and then try to send the backport to prev6 via Tactics. We can request the build wizards to wait for this change before they generate a build. |
* Implement UnixFileMode APIs on Unix. * Throw PNSE on Windows, add UnsupportedOSPlatform. * Fix API compat issue. * Borrow a few things from SafeFileHandle API PR to this compiles. * Fix System.IO.FileSystem.AccessControl compilation. * Add xml docs. * Replace Interop.Sys.Permissions to System.IO.UnixFileMode. * Throw PNSE immediately on Windows. * Add ODE to xml docs of methods that accept a handle. * Don't throw (PNSE) from FileSystemInfo.UnixFileMode getter on Windows. * Minor style fix. * Get rid of some casts. Co-authored-by: Eric Erhardt <[email protected]> * Add tests for creating a file/directory with UnixFileMode. * Some CI envs don't have a umask exe, try retrieving via a shell builtin. * Update expected test mode values. * Fix OSX * Fix Windows build. * Add ArgumentException tests. * Fix Windows build. * Add get/set tests. * Update test for Windows. * Make setters target link instead of link target. * Linux: fix SetUnixFileMode * Fix OSX compilation. * Try make all tests pass in CI. * For link, operate on target permissions. * Skip tests on Browser. * Add tests for 'Get' that doesn't use a 'Set' first. * Don't perform exist check for handles. * Fix Get test for wasm. * Review xml comments. * Add comment to test. * GetUnixFileMode for handle won't throw UnauthorizedAccessException. * Apply suggestions from code review Co-authored-by: Eric Erhardt <[email protected]> * PR feedback. * Update enum doc to say 'owner' instead of 'user'. * Use UnixFileMode in library. * Use UnixFileMode in library tests. * Fix Windows build. * Fix missing FileAccess when changing to FileStreamOptions API. * PR feedback. * Fix Argument_InvalidUnixCreateMode message. Co-authored-by: Adam Sitnik <[email protected]> Co-authored-by: Eric Erhardt <[email protected]> Co-authored-by: Adam Sitnik <[email protected]>
* Implement UnixFileMode APIs (#69980) * Implement UnixFileMode APIs on Unix. * Throw PNSE on Windows, add UnsupportedOSPlatform. * Fix API compat issue. * Borrow a few things from SafeFileHandle API PR to this compiles. * Fix System.IO.FileSystem.AccessControl compilation. * Add xml docs. * Replace Interop.Sys.Permissions to System.IO.UnixFileMode. * Throw PNSE immediately on Windows. * Add ODE to xml docs of methods that accept a handle. * Don't throw (PNSE) from FileSystemInfo.UnixFileMode getter on Windows. * Minor style fix. * Get rid of some casts. Co-authored-by: Eric Erhardt <[email protected]> * Add tests for creating a file/directory with UnixFileMode. * Some CI envs don't have a umask exe, try retrieving via a shell builtin. * Update expected test mode values. * Fix OSX * Fix Windows build. * Add ArgumentException tests. * Fix Windows build. * Add get/set tests. * Update test for Windows. * Make setters target link instead of link target. * Linux: fix SetUnixFileMode * Fix OSX compilation. * Try make all tests pass in CI. * For link, operate on target permissions. * Skip tests on Browser. * Add tests for 'Get' that doesn't use a 'Set' first. * Don't perform exist check for handles. * Fix Get test for wasm. * Review xml comments. * Add comment to test. * GetUnixFileMode for handle won't throw UnauthorizedAccessException. * Apply suggestions from code review Co-authored-by: Eric Erhardt <[email protected]> * PR feedback. * Update enum doc to say 'owner' instead of 'user'. * Use UnixFileMode in library. * Use UnixFileMode in library tests. * Fix Windows build. * Fix missing FileAccess when changing to FileStreamOptions API. * PR feedback. * Fix Argument_InvalidUnixCreateMode message. Co-authored-by: Adam Sitnik <[email protected]> Co-authored-by: Eric Erhardt <[email protected]> Co-authored-by: Adam Sitnik <[email protected]> * UnixFileMode: address remaining feedback. (#71188) Co-authored-by: Tom Deseyn <[email protected]> Co-authored-by: Eric Erhardt <[email protected]>
Hey @tmds, from this discussion #69980 (comment) I can take care of replacing |
Implements #67837.